/*******************************************************************************
 * Copyright (c) 2001 Boris Pruessmann and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Common Public License v0.5
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v05.html
 * 
 * Contributors:
 *    Boris Pruessmann - Initial implementation.
 *	  David Corbin - added images, MicroPlugin implementation, 
 *                   static getClientName() method
 ******************************************************************************/
package net.sourceforge.perforce.ui;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import net.sourceforge.perforce.core.IProviderFactory;
import net.sourceforge.perforce.core.PerforceCorePlugin;
import net.sourceforge.perforce.core.PerforceSynchronizer;
import net.sourceforge.perforce.core.internal.P4TeamProvider;
import net.sourceforge.perforce.core.internal.api.PerforceServer;
import net.sourceforge.perforce.core.internal.events.AddDeleteMoveListener;
import net.sourceforge.perforce.core.resources.LocalFile;
import net.sourceforge.perforce.core.resources.RemoteFile;
import net.sourceforge.perforce.core.resources.RemoteFolder;
import net.sourceforge.perforce.ui.internal.MoveDeleteHook;
import net.sourceforge.perforce.ui.internal.PerforceFileModificationValidator;
import net.sourceforge.perforce.ui.internal.Policy;
import net.sourceforge.perforce.ui.model.PerforceAdapterFactory;
import org.eclipse.core.resources.IFileModificationValidator;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.team.IMoveDeleteHook;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPluginDescriptor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.plugin.AbstractUIPlugin;

/**
  * @version  $Revision: 68 $
  * @author   <a href="mailto:bpruessmann@users.sourceforge.net">Boris Pruessmann</a>
  */
public class PerforceUIPlugin 
	extends AbstractUIPlugin 
	implements MicroPlugin, IPropertyChangeListener
{
	public static final String ID        = "net.sourceforge.perforce.ui"; //$NON-NLS-1$

	public static final String CALCULATE_DIRTY_PREFERENCE = ID + ".preferences.calculate_dirty"; //$NON-NLS-1$
	public static final String DELETE_AFFECTS_CHANGELIST = ID + ".preferences.delete_affects_changelist"; //$NON-NLS-1$

	public static final String ICON_PATH_FULL = "icons/full/";             //$NON-NLS-1$
	public static final String IMG_CLEAR = "clcl16/clear_co.gif";          //$NON-NLS-1$
	public static final String IMG_ROOTELEMENT = "clcl16/depot.gif"; //$NON-NLS-1$

	public static final String IMG_REPOSITORY = "cview16/depot_view.gif"; //$NON-NLS-1$
	public static final String IMG_ERROR = "misc/error.gif"; //$NON-NLS-1$
		
	public static final String IMG_SUBMITTED_CHANGELIST = "clcl16/submitted_cl.gif"; //$NON-NLS-1$		

	public static final String OVR_HASREMOTE   = "ovr/hasRemote.gif";   //$NON-NLS-1$
	public static final String OVR_OUTOFDATE   = "ovr/outOfDate.gif";   //$NON-NLS-1$	
	public static final String OVR_OPENFORADD  = "ovr/openForAdd.gif";  //$NON-NLS-1$	
	public static final String OVR_OPENFOREDIT = "ovr/openForEdit.gif"; //$NON-NLS-1$	

	public static final String OVR_OTHER_OPENFOREDIT = "ovr/otherOpenForEdit.gif"; //$NON-NLS-1$		
	
	
	private static PerforceUIPlugin instance;
	
	private Map imageDescriptors = new HashMap();
	
	/**
	  * Constructor for PerforceUIPlugin.
	  * @param descriptor
	  */
	public PerforceUIPlugin(IPluginDescriptor descriptor)
	{
		super(descriptor);
		
		Policy.assertNull(instance);
		instance = this;	
		MicroPluginFactory.setPlugin(this);
		
		getPreferenceStore().addPropertyChangeListener(this);
	}

	/**
	  * Returns the plugin's singleton instance.
	  */
	public static PerforceUIPlugin getPlugin()
	{
		Policy.assertNotNull(instance);
		return instance;
	}
	
	public static IWorkbenchPage getActivePage() 
	{
		IWorkbenchWindow window = getPlugin().getWorkbench().getActiveWorkbenchWindow();
		
		if (window == null) 
		{
			return null;
		}
		else
		{
			return window.getActivePage();
		}
	}

	/** Returns the workspace instance. */
	public static IWorkspace getWorkspace() 
	{
		return ResourcesPlugin.getWorkspace();
	}
	
	/*
	 * @see Plugin#startup()
	 */
	public void startup() 
		throws CoreException
	{
		super.startup();		
		Policy.localize("net.sourceforge.perforce.ui.messages"); //$NON-NLS-1$
	
		PerforceSynchronizer.startup();
				
		PerforceAdapterFactory factory = new PerforceAdapterFactory();
		Platform.getAdapterManager().registerAdapters(factory, PerforceServer.class);
		Platform.getAdapterManager().registerAdapters(factory, RemoteFolder.class);
		Platform.getAdapterManager().registerAdapters(factory, RemoteFile.class);
		Platform.getAdapterManager().registerAdapters(factory, LocalFile.class);
		
		PerforceCorePlugin.getPlugin().setProviderFactory(new IProviderFactory() 
		{
			/** @see IProviderFactory#createMoveDeleteHook */
			public IMoveDeleteHook createMoveDeleteHook(P4TeamProvider provider) 
			{
				return new MoveDeleteHook(provider);
			}

			/** @see IProviderFactory#createFileModificationValidator */
			public IFileModificationValidator createFileModificationValidator(P4TeamProvider provider) 
			{
				return new PerforceFileModificationValidator();				
			}
		});
	
		initializeImages();
		initializeCorePreferences();		
	}
	
	/*
	 * @see Plugin#shutdown()
	 */
	public void shutdown() 
		throws CoreException
	{
		PerforceDecorator.shutdown();
		PerforceSynchronizer.shutdown();
		
		super.shutdown();
	}
	
	public static void log(IStatus status)
	{
		getPlugin().getLog().log(status);
	}

	public static void logError(String message, Throwable throwable) 
	{
		getPlugin().getLog().log(new Status(IStatus.ERROR, PerforceUIPlugin.ID, IStatus.ERROR, message, throwable));
	}
	
	private void initializeImages()
	{
		URL baseURL = getDescriptor().getInstallURL();
		
		createImageDescriptor(IMG_CLEAR, baseURL);
		createImageDescriptor(IMG_ROOTELEMENT, baseURL);
		createImageDescriptor(IMG_ERROR, baseURL);
		createImageDescriptor(IMG_REPOSITORY, baseURL);
		createImageDescriptor(IPerforceUIConstants.IMG_REFRESH, baseURL);
		
		
		createImageDescriptor(IPerforceUIConstants.IMG_CLIENT_CHANGELISTS, baseURL);
		createImageDescriptor(IPerforceUIConstants.IMG_CLIENT_CHANGELIST, baseURL);		
		createImageDescriptor(IPerforceUIConstants.IMG_OTHER_CHANGELISTS, baseURL);
		createImageDescriptor(IPerforceUIConstants.IMG_OTHER_CHANGELIST, baseURL);
		createImageDescriptor(IMG_SUBMITTED_CHANGELIST, baseURL);		
		
		createImageDescriptor(IPerforceUIConstants.IMG_PERFORCE_SERVER, baseURL);
		createImageDescriptor(IPerforceUIConstants.IMG_HEAD_REV, baseURL);
		createImageDescriptor(IPerforceUIConstants.IMG_NEWLOCATION, baseURL);
		createImageDescriptor(IPerforceUIConstants.IMG_WIZBAN_SHARE, baseURL);
		
		createImageDescriptor(OVR_HASREMOTE, baseURL);
		createImageDescriptor(OVR_OUTOFDATE, baseURL);		
		createImageDescriptor(OVR_OPENFORADD, baseURL);
		createImageDescriptor(OVR_OPENFOREDIT, baseURL);		
		
		createImageDescriptor(OVR_OTHER_OPENFOREDIT, baseURL);		
	}	
	
	protected void createImageDescriptor(String id, URL baseURL) 
	{
		URL url = null;
		try 
		{
			url = new URL(baseURL, ICON_PATH_FULL + id);
		} 
		catch (MalformedURLException e) 
		{
			// Ignored!
		}
		
		ImageDescriptor desc = ImageDescriptor.createFromURL(url);
		imageDescriptors.put(id, desc);
	}	

	public ImageDescriptor getImageDescriptor(String id) 
	{
		return (ImageDescriptor) imageDescriptors.get(id);
	}
	
	/** @see AbstractUIPlugin#initializeDefaultPreferences(IPreferenceStore) */
	protected void initializeDefaultPreferences(IPreferenceStore store)
	{
		store.setDefault(CALCULATE_DIRTY_PREFERENCE, true);
		store.setDefault(DELETE_AFFECTS_CHANGELIST, true);
		
		store.setDefault(
			IPerforceUIConstants.PREF_DIRTY_FLAG, P4DecoratorConfiguration.DEFAULT_DIRTY_FLAG);
		store.setDefault(
			IPerforceUIConstants.PREF_ADDED_FLAG, P4DecoratorConfiguration.DEFAULT_ADDED_FLAG);
		store.setDefault(
			IPerforceUIConstants.PREF_FILETEXTFORMAT, 
			P4DecoratorConfiguration.DEFAULT_FILETEXTFORMAT);
		store.setDefault(
			IPerforceUIConstants.PREF_FOLDERTEXTFORMAT,
			P4DecoratorConfiguration.DEFAULT_FOLDERTEXTFORMAT);
		store.setDefault(
			IPerforceUIConstants.PREF_PROJECTTEXTFORMAT,
			P4DecoratorConfiguration.DEFAULT_PROJECTTEXTFORMAT);
			
		store.setDefault(
			IPerforceUIConstants.PREF_SHOW_TASKS_ON_ADD,
			true);
	}
	
	/** Propagates the preferences to the core plugin. */
	private void initializeCorePreferences()
	{
		IPreferenceStore store = getPreferenceStore();
		
		PerforceCorePlugin.getPlugin().setShowTasksOnAdd(
			store.getBoolean(IPerforceUIConstants.PREF_SHOW_TASKS_ON_ADD));
	}

	public IWorkspaceRoot getWorkspaceRoot()
	{
		return ResourcesPlugin.getWorkspace().getRoot();
	}

	/** @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(PropertyChangeEvent) */	
	public void propertyChange(PropertyChangeEvent event) 
	{
		try 
		{
			String property = event.getProperty();
			if (property.equals(IPerforceUIConstants.PREF_SHOW_TASKS_ON_ADD)) 
			{
				boolean b = ((Boolean) event.getNewValue()).booleanValue();				
				PerforceCorePlugin.getPlugin().setShowTasksOnAdd(b);				
				
				if (b) 
				{
					AddDeleteMoveListener.refreshAllMarkers();
				} 
				else 
				{
					AddDeleteMoveListener.clearAllPerforceMarkers();
				}
			}
		} 
		catch (CoreException e) 
		{
			log(e.getStatus());
		}
	}
}
